package com.css.fxfzaqbz.modules.callJcData.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.PageUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson.JSONObject;
import com.css.fxfzaqbz.base.response.RestResponse;
import com.css.fxfzaqbz.constants.FxfzConstants;
import com.css.fxfzaqbz.constants.YNEnum;
import com.css.fxfzaqbz.modules.base.service.HypergraphService;
import com.css.fxfzaqbz.modules.callJcData.constonts.RedisKeyConstants;
import com.css.fxfzaqbz.modules.callJcData.entity.Gasholder;
import com.css.fxfzaqbz.modules.callJcData.entity.PageResult;
import com.css.fxfzaqbz.modules.callJcData.exception.ShpFieldException;
import com.css.fxfzaqbz.modules.callJcData.param.DataVersionPageParam;
import com.css.fxfzaqbz.modules.callJcData.param.GasholderQueryParams;
import com.css.fxfzaqbz.modules.callJcData.param.SysDataVersionPageParam;
import com.css.fxfzaqbz.modules.callJcData.repository.GasholderRepository;
import com.css.fxfzaqbz.modules.callJcData.result.ParsingResult;
import com.css.fxfzaqbz.modules.callJcData.service.GasholderService;

import com.css.fxfzaqbz.modules.callJcData.vo.ListVo;
import com.css.fxfzaqbz.modules.supergraph.entity.CqgDataEntity;
import com.css.fxfzaqbz.modules.supergraph.exception.CustomException;
import com.css.fxfzaqbz.modules.supergraph.vo.GasholderBrVO;
import com.css.fxfzaqbz.modules.supergraph.vo.SourceOfDangerBrVO;
import com.css.fxfzaqbz.modules.threadpool.ThreadPoolManage;
import com.css.fxfzaqbz.util.*;
import com.css.fxfzaqbz.util.fileParsing.shp.ShpAnalyticUtil;
import com.css.fxfzaqbz.web.PlatformSessionContext;
import com.css.fxfzaqbz.zcpt.sys.entity.SUser;
import com.css.fxfzaqbz.zcpt.sys.service.SUserService;
import com.css.fxfzaqbz.zcpt.sys.service.SysAreaService;
import com.css.fxfzaqbz.zcpt.sys.service.SysRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.*;


@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class GasholderServiceImpl implements GasholderService {
    @Resource
    GasholderRepository gasholderRepository;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private SUserService sUserService;
    @Resource
    private SysRoleService sysRoleService;

    @Resource
    private SysAreaService sysAreaService;

    @Resource
    private HypergraphService hypergraphService;

    @Override
    public void save(Gasholder param) {
        param.setGaNumber(getVersionCodeNum());
        param.setGaId(UUIDGenerator.getUUID());
        param.setDelFlag(YNEnum.N.toString());
        param.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
        String userID = PlatformSessionContext.getUserID(); // 获取当前登录用户
        param.setCreateUser(userID);
        param.setUploadTime(PlatformDateUtils.getCurrentTimestamp());
        gasholderRepository.save(param);
        ThreadPoolManage.exeBizThreadPoolExecutor.execute(()->hypergraphService.getWorkspaceReload("sys_gasholder"));

    }

    @Override
    public Gasholder findById(String id) {
        return gasholderRepository.findById(id);
    }

    @Override
    public void updateById(Gasholder param) {
        String userID = PlatformSessionContext.getUserID(); // 获取当前登录用户
        param.setUpdateUser(userID);
        param.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
        gasholderRepository.updateById(param);
        ThreadPoolManage.exeBizThreadPoolExecutor.execute(()->hypergraphService.getWorkspaceReload("sys_gasholder"));

    }

    @Override
    public void deleteById(String id) {
        gasholderRepository.deleteById(id);
        ThreadPoolManage.exeBizThreadPoolExecutor.execute(()->hypergraphService.getWorkspaceReload("sys_gasholder"));

    }

    @Override
    public PageResult<Gasholder> page(GasholderQueryParams param) {
        int tPNum = param.getPage();
        param.setPage(param.getRows() * (Math.max(param.getPage(), 1) - 1));
        List<Gasholder> list = gasholderRepository.page(param);
        Integer total = gasholderRepository.countForPage(param);
        return new PageResult<>(tPNum, param.getRows(), PageUtil.totalPage(total, param.getRows()), total, list);

    }

    @Override
    public void dataImport(InputStream inputStream) {
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        List<Gasholder> list = reader.readAll(Gasholder.class);
        for (Gasholder gasholder : list) {
            String userID = PlatformSessionContext.getUserID();
            gasholder.setCreateUser(userID);
            this.save(gasholder);
        }
    }

    @Override
    public void exportExcel(HttpServletResponse response) throws IOException {
        List<Gasholder> list = gasholderRepository.exportExcel();
        FileUtil2.exportExcel(list, "储气罐数据表", "sheet", Gasholder.class, "GasholderExcel", response);
    }

    @Override
    public List<Gasholder> getDataByTypeAndVersion(SysDataVersionPageParam sysDataVersionPageParam) {
        return gasholderRepository.getDataByTypeAndVersion(sysDataVersionPageParam);
    }

    @Override
    public RestResponse saveShpTemporaryData(ParsingResult shpData) {
        //生成临时版本号
        try {
            String dataVersion = UUID.randomUUID().toString().replaceAll("-", "");
            List<Gasholder> list = getList(shpData.getShpList(), dataVersion);
            if (list==null){
                return RestResponse.fail("字段数量不符合要求");
            }
            gasholderRepository.byShpBatchSave(list);
            ListVo listVo = new ListVo("0", null, dataVersion, "储气罐", null, list);
            return RestResponse.succeed(listVo);
        } catch (ShpFieldException e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail(e.getMessage());
        } catch (IndexOutOfBoundsException e1) {
            log.error(e1.getMessage(), e1);
            return RestResponse.fail("字段数量不符合要求");
        }
    }

    @Override
    public void deleteByVersion(String versionCode) {
        gasholderRepository.deleteByVersion(versionCode);
    }

    @Override
    public void updateByLsVersion(String tempVersionCode, String dataVersion, Integer sf) {
        gasholderRepository.updateByLsVersion(tempVersionCode, dataVersion, sf);
    }

    @Override
    public List<Gasholder> getYwData(String versionCode) {
        return gasholderRepository.getYwData(versionCode);
    }

    @Override
    public void updateLs(String versionCode, String tempVersionCode) {
        gasholderRepository.updateLs(versionCode, tempVersionCode);
    }

    @Override
    public void saveGasholderBr(GasholderBrVO gasholderBrVO) {
        gasholderRepository.saveGasholderBr(gasholderBrVO);
    }

    @Override
    public void deleteGasholderBr(String iaId,String dataVersion) {
        gasholderRepository.deleteGasholderBr(iaId,dataVersion);
    }

    @Override
    public List<Gasholder> getDataBySSQAndVersion(SourceOfDangerBrVO sourceOfDangerBrVO) {
        return gasholderRepository.getDataBySSQAndVersion(sourceOfDangerBrVO);
    }

    @Override
    public Map<String,Object> getCqgDataVersion(CqgDataEntity cqgDataEntity) {
        return gasholderRepository.getCqgDataVersion(cqgDataEntity);
    }

    @Override
    public RestResponse getFyYwData(DataVersionPageParam dataVersionPageParam) {
        //判断当前登录人身份
        String role = getRole();
        return gasholderRepository.getFyYwData(dataVersionPageParam,role);
    }

    @Override
    public List<Gasholder> getGasholderNumByVersion(String versionCode) {
        return gasholderRepository.getGasholderNumByVersion(versionCode);
    }

    private List<Gasholder> getList(List<List<Object>> shpList, String dataVersion) throws ShpFieldException {
        String userID = PlatformSessionContext.getUserID(); // 获取当前登录用户
        ArrayList<Gasholder> arrayList = new ArrayList<>();
        for (int i = 0; i < shpList.size(); i++) {
            List<Object> list = shpList.get(i);
       /*     if (list.size()!=34){
                return null;
            }*/
            Gasholder obj = new Gasholder();
            //临时版本号
            obj.setDataVersion(dataVersion);
            //当前用户
            obj.setZdNum(list.size());
            obj.setCreateUser(userID);
            obj.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
            obj.setDelFlag(YNEnum.N.toString());
            obj.setUploadTime(new Date());
            obj.setGaNumber(getVersionCodeNum());
            obj.setGaId(UUID.randomUUID().toString().replaceAll("-", ""));
            obj.setGeom(list.get(0).toString());
            obj.setProvince(ShpAnalyticUtil.getStringVal(list.get(1), "省", true));
            obj.setCity(ShpAnalyticUtil.getStringVal(list.get(2), "市", true));
            obj.setCounty(ShpAnalyticUtil.getStringVal(list.get(3), "区（县）", true));
            obj.setGaLongitude(ShpAnalyticUtil.getDoubleVal(list.get(4), "经度", true));
            obj.setGaLatitude(ShpAnalyticUtil.getDoubleVal(list.get(5), "纬度", true));
            obj.setGaName(ShpAnalyticUtil.getStringVal(list.get(6), "储气罐名称", true));
            obj.setGaXh(ShpAnalyticUtil.getStringVal(list.get(7), "型号", true));
            obj.setGaGcrj(ShpAnalyticUtil.getDoubleVal(list.get(8), "公称容积", true));
            obj.setGaGzyl(ShpAnalyticUtil.getDoubleVal(list.get(9), "工作压力", true));
            obj.setGaTtnj(ShpAnalyticUtil.getDoubleVal(list.get(10), "筒体内径", true));
            obj.setGaTtgd(ShpAnalyticUtil.getDoubleVal(list.get(11), "筒体高度", true));
            obj.setGaTtftbh(ShpAnalyticUtil.getDoubleVal(list.get(12), "筒体、封头壁厚", true));
            obj.setGaCkzl(ShpAnalyticUtil.getDoubleVal(list.get(13), "参考重量", true));
            obj.setGaJgcl(ShpAnalyticUtil.getStringVal(list.get(14), "结构材料", true));
            obj.setGaDgcd(ShpAnalyticUtil.getDoubleVal(list.get(15), "导轨长度", false));
            obj.setGaDggd(ShpAnalyticUtil.getDoubleVal(list.get(16), "导轨高度", false));
            obj.setGaDgzfhd(ShpAnalyticUtil.getDoubleVal(list.get(17), "导轨中腹厚度", false));
            obj.setGaJcxs(ShpAnalyticUtil.getStringVal(list.get(18), "基础形式", false));
            obj.setGaClxh(ShpAnalyticUtil.getStringVal(list.get(19), "材料型号", false));
            obj.setGaTxml(ShpAnalyticUtil.getDoubleVal(list.get(20), "弹性模量", false));
            obj.setGaQfyl(ShpAnalyticUtil.getDoubleVal(list.get(21), "屈服应力", false));
            obj.setGaXyyl(ShpAnalyticUtil.getDoubleVal(list.get(22), "许用应力", false));
            obj.setGaCdlb(ShpAnalyticUtil.getStringVal(list.get(23), "场地类别", true));
            obj.setGaLdsyhcd(ShpAnalyticUtil.getStringVal(list.get(24), "6度时液化程度", false));
            obj.setGaQdsyhcd(ShpAnalyticUtil.getStringVal(list.get(25), "7度时液化程度", false));
            obj.setGaBdsyhcd(ShpAnalyticUtil.getStringVal(list.get(26), "8度时液化程度", false));
            obj.setGaJdsyhcd(ShpAnalyticUtil.getStringVal(list.get(27), "9度时液化程度", false));
            obj.setGaLdszxcd(ShpAnalyticUtil.getStringVal(list.get(28), "6度时震陷程度", false));
            obj.setGaQdszxcd(ShpAnalyticUtil.getStringVal(list.get(29), "7度时震陷程度", false));
            obj.setGaBdszxcd(ShpAnalyticUtil.getStringVal(list.get(30), "8度时震陷程度", false));
            obj.setGaJdszxcd(ShpAnalyticUtil.getStringVal(list.get(31), "9度时震陷程度", false));
            obj.setGaJdszxcd(ShpAnalyticUtil.getStringVal(list.get(32), "建设年代", false));
            obj.setGaJdszxcd(ShpAnalyticUtil.getStringVal(list.get(33), "设防烈度", false));
            arrayList.add(obj);
        }
        return arrayList;
    }


    private String getVersionCodeNum() {
        return this.getVersionCode();
    }

    public synchronized String getVersionCode() {
        String dataVersionCodeSerialNumber = stringRedisTemplate.opsForValue().get(RedisKeyConstants.DATA_GASHOLDER_NUMBER_KEY);
        if (StringUtils.isBlank(dataVersionCodeSerialNumber)) {
            dataVersionCodeSerialNumber = "001";
        } else {
            StringBuilder stringBuilder = new StringBuilder();
            String t = String.valueOf(Integer.parseInt(dataVersionCodeSerialNumber) + 1);
            for (int i = t.length(); i < 5; i++) {
                stringBuilder.append("0");
            }
            dataVersionCodeSerialNumber = stringBuilder.append(t).toString();
        }
        stringRedisTemplate.opsForValue().set(RedisKeyConstants.DATA_GASHOLDER_NUMBER_KEY, dataVersionCodeSerialNumber);
        stringRedisTemplate.expireAt(RedisKeyConstants.DATA_GASHOLDER_NUMBER_KEY, Date.from(LocalDateTime.of(LocalDate.now(), LocalTime.MAX).toInstant(ZoneOffset.of("+8"))));
        return DateUtil.format(new Date(), "yyyyMMdd") + "CQ" + dataVersionCodeSerialNumber;
    }



    public String getRole() {
        String userId = PlatformSessionContext.getUserID();
        String user = sUserService.getSUser(userId);
        SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
        String role = sysRoleService.getRoleByUserId(userId);
        List<Map> maps = JSONObject.parseArray(role, Map.class);//一个人可能有多个角色
        //当前登录人所有的角色
        StringBuilder roles = new StringBuilder();
        for (int i = 0; i < maps.size(); i++) {
            Map map = maps.get(i);
            roles.append(map.get("roleCode") + ",");
        }
        String allRole = roles.toString();

        //如果所有角色包括国家级管理员
        if (allRole.contains(FxfzConstants.AQBZ_GJJGLY_ROLE)) {
            return "0";
        }
        //如果所有角色包括省级管理员
        if (allRole.contains(FxfzConstants.AQBZ_SJGLY_ROLE)) {
            if (PlatformObjectUtils.isEmpty(sUser.getProvinceId())) {
                throw new CustomException("请完善当前登陆人所属省市信息");
            }
            String areaName = sysAreaService.getAreaNameByAreaId(sUser.getProvinceId());
            return areaName;
        }
        return "1";
    }


}
